<?php

class ItemRequestsController extends BaseController {
	static $adminTypePk;
	public function __construct()
    {
        $this->beforeFilter('isAdminGet', array('only' => array('resolveRequest')));
    }
    public function replaceTrashedUsers($requests)
    {
    	foreach($requests as $request)
    	{
    		if(!is_object($request->requestedBy))
    		{
				$request->requestedBy = User::withTrashed()->find($request->requested_by_fk);
			}
    	}
    	return $requests;
    }
	public function showRequests()
	{
		$requests = ItemRequest::where("pk", ">", "0");
		$fromDate = Input::get('from');
		$toDate = Input::get('to');
		$status = Input::get('status');
		$historyTabSelected = false;
		if($fromDate != "")
		{
			$requests->where("created_at", ">=", $fromDate);
			$historyTabSelected = true;
		}
		if($toDate != "")
		{
			$requests->where("created_at", "<=", $toDate);
			$historyTabSelected = true;
		}
		if($status != "")
		{
			$requests->where("request_status_fk", "=", $status);
			$historyTabSelected = true;
		}
		if(Auth::user()->userType->pk == ItemRequestsController::$adminTypePk)
		{
			$userPk = Input::get("user");
			if($userPk != "")
			{
				$requests = $requests->where("requested_by_fk", "=", $userPk);
				$historyTabSelected = true;
			}
			$requests = $requests->where("request_status_fk", "=", Config::get('globals.SOLVED_REQUEST_STATUS'))->paginate(10);

			return $this->showRequestsAdmin($this->replaceTrashedUsers($requests), $historyTabSelected);
		}
		$requests = $requests->where('requested_by_fk', '=', Auth::user()->pk);
		
		return View::make('requests.requestsHome')->with('requests', $this->replaceTrashedUsers($requests->paginate(10)));
	}

	public function showRequestsAdmin($solvedRequests, $historyTabSelected)
	{
		$pendingRequests = ItemRequest::where("request_status_fk", "!=", Config::get('globals.SOLVED_REQUEST_STATUS'))->get();
		$userObjIds = DB::table('item_requests')->select("requested_by_fk")->distinct()->get();
		$userIds = array(-999);
		$users = new User;
		foreach($userObjIds as $userObjId)
		{
			array_push($userIds, $userObjId->requested_by_fk);
		}
		$users = $users->whereIn('pk', $userIds)->get();
		return View::make('requests.requestsHomeAdmin')->with('solvedRequests', $solvedRequests)->with('pendingRequests', $pendingRequests)->with("users", $users)->with("historyTabSelected", $historyTabSelected);
	}

	public function showItems()
	{
		$error = false;
		$message = "";
		$html;
		$response;
		$showItemsAdminPopup;
		$requestItems;
		$requestTypes = array();
		try
		{
			$request = ItemRequest::find(Input::get('pk'));
			$requestItems = $request->requestItems;
			$showItemsAdminPopup = Auth::user()->userType->pk == ItemRequestsController::$adminTypePk && !Util::checkIfSolvedRequest($request->request_status_fk);
			if($showItemsAdminPopup)
			{
				foreach (ItemRequestType::all() as $type) {
					$requestTypes[$type->description] = $type->pk;
				}	
				$html = View::make('requests.showItemsAdminPopup')->with('requestItems', $requestItems)->render();
			}
			else
			{
				$html = View::make('requests.showItemsPopup')->with('requestItems', $requestItems)->render();
			}
			
		}
		catch(Exception $e)
		{
			$error = true;
			$message = "Error: ".$e->getMessage();
		}
		if($error)
		{
			$response = array("error" => $error, "message" => $message);
			
		}
		else
		{
			$response = array("error" => $error, "html" => $html);
			if($showItemsAdminPopup)
			{
				$response['requestItems'] = $requestItems;
				$response['types'] = $requestTypes;
			}
		}
		return json_encode($response);
	}
	public function processValidator($validator)
	{
		if($validator->fails())
				{
					$ms = "";
					foreach ($validator->messages()->all('-:message') as $message)
					{
					    $ms .= $message;
					}
					throw new Exception($ms);
					
				}
	}
	public function getRequestItemStatusIds()
	{
		$requestItemStatus = "";
		foreach(ItemRequestItemStatus::all() as $status)
		{
			$requestItemStatus .= $status->pk.",";
		}
		return trim($requestItemStatus, ",");
	}

	public function getRequestStatusIds()
	{
		$requestStatus = "";
		foreach(ItemRequestStatus::all() as $status)
		{
			$requestStatus .= $status->pk.",";
		}
		return trim($requestStatus, ",");
	}
	public function resolveRequest()
	{
		$error = false;
		$message = "";
		$dispatchedRequest = true;
		try
		{			
			$request = ItemRequest::find(Input::get("requestPk"));
			$requestItems = Input::get("itemRequests");
			if(empty($requestItems))
			{
				throw new Exception("No items requests were received by the server.");
			}
			$itemRequestController = $this;
			DB::transaction(function() use ($request, $requestItems, &$dispatchedRequest, $itemRequestController){
				$requestItemStatus = $itemRequestController->getRequestItemStatusIds();
				foreach($requestItems as $data)
				{
					$requestItem = ItemRequestItem::find($data['id']);
					if($requestItem->request_fk != $request->pk)
					{
						throw new Exception("An error occurrerd. The requested items don't match the request");
					}

					$validator = Validator::make(
					    array(
					    	'status'=> $data['status'],
					        'amount' => $data['amount'],
					        'comment' => $data['comment']
					    ),
					    array(
					    	'status'=> 'required|numeric|in:'.$requestItemStatus,
					        'amount' => 'required|numeric|min:1|max:'.$requestItem->item->amount,
					        'comment' => 'max:255'
					    )
					);

					$itemRequestController->processValidator($validator);

					$requestItem->request_item_status_fk = $data['status'];
					$requestItem->amount = $data['amount'];
					$requestItem->comment = $data['comment'];
					$dispatchedOrRejectedItemRequest = Util::checkIfDispatchedItemRequest($requestItem->request_item_status_fk) || Util::checkIfRejectedItemRequest($requestItem->request_item_status_fk);
					$dispatchedRequest = $dispatchedRequest && $dispatchedOrRejectedItemRequest;
					$requestItem->save();
				}

				if($dispatchedRequest)
				{
					foreach($requestItems as $data)
					{
						$requestItem = ItemRequestItem::find($data['id']);
						if(Util::checkIfDispatchedItemRequest($requestItem->request_item_status_fk))
						{
							$item = $requestItem->item;
							$newAmount = floatval($item->amount) - floatval($requestItem->amount);
							if($newAmount < 0)
							{
								throw new Exception("No puede despachar ".$requestItem->amount." unidades del item ".$item->name." porque hay ".$item->amount." en el inventario.");
							}
							$item->amount = $newAmount;
							$item->save();
						}

					}
					$request->request_status_fk = Config::get("globals.SOLVED_REQUEST_STATUS");
					$request->approved_by_fk = Auth::user()->pk;
				}
				else
				{
					$request->request_status_fk = Config::get("globals.RESOLVING_REQUEST_STATUS");
				}
				$request->save();
			});
			
		}
		catch(Exception $e)
		{
			$error = true;
			$message = "Error: ".$e->getMessage();
		}
		if($error)
		{
			$response = array("error" => $error, "message" => $message);
			
		}
		else
		{
			$response = array("error" => $error, "dispatchedRequest"=>$dispatchedRequest);
		}
		return json_encode($response);
	}

	public function getRequestCreate()
	{
		$error = false;
		$message = "";
		$html;
		$response;
		$requestTypes;
		try
		{
			$items = Item::all();
			$html = View::make('requests.createPopup')->with('items', $items)->render();
			$requestTypes = array();
			foreach (ItemRequestType::all() as $type) {
				$requestTypes[$type->description] = $type->pk;
			}
		}
		catch(Exception $e)
		{
			$error = true;
			$message = "Error: ".$e->getMessage();
		}
		if($error)
		{
			$response = array("error" => $error, "message" => $message);
			
		}
		else
		{
			$response = array("error" => $error, "html" => $html, "request"=>"{}", "types"=>$requestTypes);
		}
		return json_encode($response);
	}

	public function saveRequest()
	{
		$error = false;
		$message = "";
		$html;
		$response;
		$requestArray = Input::get('request');
		$items = $requestArray['items'];
		//print_r($items);
		try
		{
			$controller = $this;
			DB::transaction(function($items) use ($items, $controller){
				$request = new ItemRequest;
				$request->requested_by_fk = Auth::user()->pk;
				$request->request_status_fk = ItemRequestStatus::where("description", "=", "enviada")->firstOrFail()->pk;
				$request->save();
				$requestStatus = $controller->getRequestStatusIds();
				foreach($items as $key => $value)
				{
					$requestItem = new ItemRequestItem;
					$requestItem->request_fk = $request->pk;
					$requestItem->request_type_fk = $value["type"];
					$requestItem->request_item_status_fk = ItemRequestItemStatus::where("description", "=", "pendiente")->firstOrFail()->pk;
					$requestItem->amount = $value["amount"];
					$requestItem->item_fk = $key;
					$validator = Validator::make(
					    array(
					    	'type'=> $value['type'],
					        'amount' => $value['amount']
					    ),
					    array(
					    	'type'=> 'required|numeric|in:'.$requestStatus,
					        'amount' => 'required|numeric|min:1|max:'.$requestItem->item->amount
					    )
					);
					$controller->processValidator($validator);
					$requestItem->save();
				}

				$user = Auth::user();
				$adminEmail = User::where("user_type_fk", "=", Config::get("globals.adminTypePk"))->firstOrFail()->email;
				$data = array("user"=>$user, "itemRequests"=>$request->requestItems());
				Mail::send('emails.itemRequest', $data, function($message) use ($user, $adminEmail)
				{
				    $message->from('admin@labbyinventory.x10host.com', $user->getFullName());
				    $message->subject("Pedido de un nuevo item");
				    $message->to($adminEmail);
				});	
			});
			
		}
		catch(Exception $e)
		{
			$error = true;
			$message = "Error: ".$e->getMessage();
		}
		if($error)
		{
			$response = array("error" => $error, "message" => $message);
			
		}
		else
		{
			$response = array("error" => $error);
		}
		return json_encode($response);
	}

	public function searchItems()
	{
		$error = false;
		$message = "";
		$response;
		$html;
		try
		{
			$irc = new ItemsController;
			$items = $irc->searchItems(Input::get("criteria"));
			$html = View::make("requests.itemList")->with("items", $items)->render();		
		}
		catch(Exception $e)
		{
			$error = true;
			$message = "Error: ".$e->getMessage();
		}
		if($error)
		{
			$response = array("error" => $error, "message" => $message);
			
		}
		else
		{
			$response = array("error" => $error, "html"=>$html);
		}
		return json_encode($response);
	}

	public function requestNewItem()
	{
		$error = false;
		$message = "";
		$response;
		$html;
		try
		{
			$admins = User::where("user_type_fk", "=", Config::get("globals.adminTypePk"))->get();
			$html = View::make("requests.requestNewItemPopup")->with("admins", $admins)->render();		
		}
		catch(Exception $e)
		{
			$error = true;
			$message = "Error: ".$e->getMessage();
		}
		if($error)
		{
			$response = array("error" => $error, "message" => $message);
			
		}
		else
		{
			$response = array("error" => $error, "html"=>$html);
		}
		return json_encode($response);
	}

	public function sendNewItemRequest()
	{
		$error = false;
		$message = "";
		$response;
		$email = "";
		try
		{
			$reference = Input::get("reference");
			$name = Input::get("name");
			$comment = Input::get("comment");
			$user = Auth::user();
			$adminEmail = User::where("pk", "=", Input::get("admin"))->firstOrFail()->email;
			$email = View::make('emails.requestNewItem')->with("reference", $reference)->with("user", $user)->with("name", $name)->with("comment", $comment)->render();
			$email .= User::where("user_type_fk", "=", Config::get("globals.adminTypePk"))->firstOrFail()->email;
			$data = array("user"=>$user, "reference"=>$reference, "name"=>$name, "comment"=>$comment);
			Mail::send('emails.requestNewItem', $data, function($message) use ($user, $adminEmail)
			{
			    $message->from('admin@labbyinventory.x10host.com', $user->getFullName());
			    $message->subject("Pedido de un nuevo item");
			    $message->to($adminEmail);
			});		
		}
		catch(Exception $e)
		{
			$error = true;
			$message = "Error: ".$e->getMessage();
		}
		if($error)
		{
			$response = array("error" => $error, "message" => $message);
			
		}
		else
		{
			$response = array("error" => $error, "email"=>$email);
		}
		return json_encode($response);
	}

	public function test()
	{
		//$item = ItemRequest::all()[0];
		//return View::make('requests.createPopup');

		Input::merge(array('requestPk' => '5'));
		Input::merge(array('itemRequests'=>array(1,2,3,4)));
		return $this->resolveRequest();
	}
}

ItemRequestsController::$adminTypePk = UserType::where('description', '=', 'admin')->firstOrFail()->pk;